package com.finger.gulimall.product.service.impl;

import com.finger.common.constant.ProductConstant;
import com.finger.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.finger.gulimall.product.entity.AttrEntity;
import com.finger.gulimall.product.service.AttrAttrgroupRelationService;
import com.finger.gulimall.product.service.AttrService;
import com.finger.gulimall.product.vo.AttrGroupWithAttrsVO;
import com.finger.gulimall.product.vo.AttrRelationVO;
import com.finger.gulimall.product.vo.SkuItemAttrGroupVo;
import jdk.nashorn.internal.ir.ContinueNode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.nio.file.attribute.GroupPrincipal;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.finger.common.utils.PageUtils;
import com.finger.common.utils.Query;

import com.finger.gulimall.product.dao.AttrGroupDao;
import com.finger.gulimall.product.entity.AttrGroupEntity;
import com.finger.gulimall.product.service.AttrGroupService;
import org.springframework.util.StringUtils;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    private AttrAttrgroupRelationService attrRelationService;

    @Autowired
    private AttrService attrService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new QueryWrapper<AttrGroupEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params, Long cateLogId) {
        QueryWrapper<AttrGroupEntity> attrGroupEntityQueryWrapper = new QueryWrapper<>();
        // 如果分类id不为空，就带上id条件
        if (cateLogId.intValue() != 0) {
            attrGroupEntityQueryWrapper.eq("catelog_id", cateLogId);
        }
        attrGroupEntityQueryWrapper.orderByAsc("sort");
        String key = (String) params.get("key");
        // 如果名字不为空，就做属性名模糊查询 或 主键查询
        if (!StringUtils.isEmpty(key)) {
            attrGroupEntityQueryWrapper.like("attr_group_name", key).or().eq("catelog_id", key);
        }
        // 分页查询数据
        IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params),
                attrGroupEntityQueryWrapper);
        return new PageUtils(page);
    }

    @Override
    public List<AttrEntity> getGroupRelation(String attrgroupId) {
        // 构建属性分组中间表查询条件，设置属性分组id 为 attrgroupId
        QueryWrapper<AttrAttrgroupRelationEntity> relationAttrQueryWrapper = new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrgroupId);
        // 查询到 attr_group_id 为 attrgroupId 全部中间表属性
        List<AttrAttrgroupRelationEntity> attrRelations = attrRelationService.list(relationAttrQueryWrapper);
        // 使用stream流 收集中间表中对应的属性id集合
        List<Long> attrIds = attrRelations.stream().map(item -> {
            Long attrId = item.getAttrId();
            return attrId;
        }).collect(Collectors.toList());

        if (attrIds.size() == 0) {
            return new ArrayList<AttrEntity>();
        }

        // 根据属性Id集合查询所有属性
        List<AttrEntity> attrEntities = attrService.listByIds(attrIds);
        return attrEntities;
    }

    // 删除属性和属性分组中间表中关联的数据，等于属性分组和属性解除关联
    @Override
    public void removeBatchAttrGroupRelation(AttrRelationVO[] attrRelationVO) {

        // 将前端传过来的VO转成准备删除的对象
        List<AttrAttrgroupRelationEntity> preDelRelations = Arrays.stream(attrRelationVO).map(item -> {
            AttrAttrgroupRelationEntity attrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(item, attrgroupRelationEntity);
            return attrgroupRelationEntity;
        }).collect(Collectors.toList());

        if (preDelRelations.size() > 0) {
            // 根据实体里的 分组id 和属性id 批量删除关联关系
            baseMapper.deleteBatchEntitys(preDelRelations);
        }

    }

    @Override
    public PageUtils getNoGroupAttr(Long attrgroupId, Map<String, Object> param) {

        // 获取当前分组实体
        AttrGroupEntity groupEntity = baseMapper.selectById(attrgroupId);
        // 获取当前菜单id
        Long catelogId = groupEntity.getCatelogId();
        // 构建查询条件：当前菜单分类下所有属性分组的id
        QueryWrapper<AttrGroupEntity> attrGroupEntity = new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId).select("attr_group_id");
        // 查询出当前菜单分类下所有属性分组实体（只包含属性分组id）
        List<AttrGroupEntity> groupEntities = baseMapper.selectList(attrGroupEntity);
        // 使用stream方式映射出所有的属性分组id
        List<Long> groupIds = groupEntities.stream().map(item -> item.getAttrGroupId()).collect(Collectors.toList());
        // 查询中间表中数据的分组id（attr_group_id）在当前菜单分类下所有的分组id中
        QueryWrapper<AttrAttrgroupRelationEntity> queryWrapper = new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", groupIds);
        // 查询
        List<AttrAttrgroupRelationEntity> currentCategoryAllAttrGroupEntitys = attrRelationService.list(queryWrapper);
        // 映射当前菜单分类下已分组的属性id集合
        List<Long> currentCategoryAllAttrIds = currentCategoryAllAttrGroupEntitys.stream().map(item -> item.getAttrId()).collect(Collectors.toList());
        // 构建查询条件 attr_type=1 属性类型必须是销售属性。enable=1 是该属性是否可用
        QueryWrapper<AttrEntity> queryCurrentCategoryAllNoRelationAttrWrapper = new QueryWrapper<AttrEntity>()
                .eq("catelog_id", catelogId).eq("attr_type", 1).eq("enable", 1);
        // 如果该分类下有绑定的有属性
        if (currentCategoryAllAttrIds.size() != 0) {
            queryCurrentCategoryAllNoRelationAttrWrapper.notIn("attr_id", currentCategoryAllAttrIds);
        }
        //分页查询数据
        IPage<AttrEntity> page = attrService.page(new Query<AttrEntity>().getPage(param), queryCurrentCategoryAllNoRelationAttrWrapper);
        // 返回
        return new PageUtils(page);
    }

    // 保存属性和属性分组中间表关系
    @Override
    public void addRelation(List<AttrRelationVO> attrRelationVO) {

        List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrRelationVO.stream().map(item -> {
            AttrAttrgroupRelationEntity attrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(item, attrgroupRelationEntity);
            return attrgroupRelationEntity;
        }).collect(Collectors.toList());
        // 批量保存属性和属性分组关系中间表数据
        attrRelationService.saveBatch(attrAttrgroupRelationEntities);
    }

    @Override
    public List<AttrGroupWithAttrsVO> getAttrGroupWithAttrs(Long catelogId) {

        /*
        // 构建查询当前菜单分类下全部属性分组的查询条件
        QueryWrapper<AttrGroupEntity> currentCategoryAttrGroupWrapper = new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId);
        // 执行查询，得到当前分类下的全部属性分组
        List<AttrGroupEntity> groupEntities = baseMapper.selectList(currentCategoryAttrGroupWrapper);
        // 创建返回集合
        List<AttrGroupWithAttrsVO> finalResult = new ArrayList<>(groupEntities.size());
        // 遍历当前分类下的全部属性分组
        for (AttrGroupEntity groupEntity : groupEntities) {
            // 创建用于返回的属性分组VO
            AttrGroupWithAttrsVO attrGroupVO = new AttrGroupWithAttrsVO();
            // 赋值
            BeanUtils.copyProperties(groupEntity,attrGroupVO);
            // 拿到分组id
            Long attrGroupId = groupEntity.getAttrGroupId();
            // 创建查询条件，通过属性分组id在属性分组和属性关系中间表中查询该分组下的所有属性id集合
            QueryWrapper<AttrAttrgroupRelationEntity> currentAttrGroupAttrIdsWrapper = new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroupId).select("attr_id");
            // 执行查询条件，返回属性分组和属性关系中间表实体
            List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrRelationService.list(currentAttrGroupAttrIdsWrapper);
            // map映射，拿到该属性分组下的所有属性id
            List<Long> attrIds = attrAttrgroupRelationEntities.stream().map(item -> item.getAttrId()).collect(Collectors.toList());
            // 根据属性id集合在属性表中查询属性
            List<AttrEntity> attrEntities = attrService.listByIds(attrIds);
            // 设置该分组下的所有属性
            attrGroupVO.setAttrs(attrEntities);
            // 添加到最终返回的集合
            finalResult.add(attrGroupVO);
        }
        */


        // 1、查询出当前分类下所有属性分组
        List<AttrGroupEntity> attrGroupEntities = baseMapper.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
        // 2、是用stream流方式把最终数据收集成集合
        List<AttrGroupWithAttrsVO> finalResult = attrGroupEntities.stream().map(item -> {
            // 2.1)、创建返回实体并赋值
            AttrGroupWithAttrsVO attrGroupWithAttrsVO = new AttrGroupWithAttrsVO();
            BeanUtils.copyProperties(item, attrGroupWithAttrsVO);
            Long attrGroupId = item.getAttrGroupId();
            // 2.2)、在属性和属性分组关系中间表中根据属性分组id查出该属性分组下的属性id
            List<Long> attrIds = attrRelationService.list(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroupId).select("attr_id")).stream().map(attr -> attr.getAttrId()).collect(Collectors.toList());

            if (attrIds.size() != 0) {
                // 2.3)、根据属性id在属性表中查出对应属性
                List<AttrEntity> attrs = attrService.listByIds(attrIds);
                // 过滤出基本属性
                List<AttrEntity> collect = attrs.stream().filter(attr -> attr.getAttrType() == ProductConstant.AttrEnume.ATTR_TYPE_BASE.getCode()).collect(Collectors.toList());
                attrGroupWithAttrsVO.setAttrs(collect);

            } else {
                // 只是单纯的设置一个空集合让前端不报错，没别的意思
                attrGroupWithAttrsVO.setAttrs(new ArrayList<AttrEntity>());
            }
            return attrGroupWithAttrsVO;
        }).collect(Collectors.toList());
        // 返回

        return finalResult;

    }

    @Cacheable(value = "attr", key = "'spuAttrGroup:'+#catalogId+'-'+#spuId", sync = true)
    @Override
    public List<SkuItemAttrGroupVo> getAttrGroupWithSpuId(Long catalogId, Long spuId) {

        List<SkuItemAttrGroupVo> skuItemAttrGroupVos = baseMapper.selectAttrGroupWithSpuId(catalogId, spuId);
        return skuItemAttrGroupVos;
    }

//    @Override
//    public List<SkuItemAttrGroupVo> getQuickAttrGroupWithSpuId(Long catalogId, Long spuId, int quickShow) {
//        List<SkuItemAttrGroupVo> skuItemAttrGroupVos = baseMapper.selectAttrGroupWithWithSpuId(catalogId,spuId);
//        return skuItemAttrGroupVos;
//    }
}